package com.ktjy.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ktjy.base.Q;
import com.ktjy.util.QueryUtil;

import java.util.List;

/**
 * Mapper层的父类接口，实现了基本的CRUD的封装
 *
 * @param <T> 数据对象实体
 * @author LILIBO
 * @since 2021-06-24
 */
public interface IMapper<T> extends BaseMapper<T> {

    /**
     * 方法前缀（通过反射调用getXxx()方法）
     */
    String METHOD_GET = "get";

    /**
     * 排除方法（反射时排除getClass()方法）
     */
    String GET_CLASS = "getClass";

    /**
     * 查询所有数据
     *
     * @return 所有数据
     */
    default List<T> selectAll() {
        return selectList(new QueryWrapper<>());
    }

    /**
     * 根据对象特征查询匹配的对象列表
     *
     * @param param 数据特征
     * @return 符合对象查询条件的对象数据
     */
    default long selectCount(T param) {
        QueryWrapper<T> qw = new QueryWrapper<>();
        if (param == null) {
            return selectCount(qw);
        }
        // 获得实体类对应的QueryWrapper对象
        qw = QueryUtil.entityQueryWrapper(param);
        return selectCount(qw);
    }

    /**
     * 根据对象特征查询匹配的对象列表
     *
     * @param param 数据特征
     * @return 符合对象查询条件的对象数据
     */
    default List<T> selectList(T param) {
        QueryWrapper<T> qw = new QueryWrapper<>();
        if (param == null) {
            return selectList(qw);
        }
        // 获得实体类对应的QueryWrapper对象
        qw = QueryUtil.entityQueryWrapper(param);
        return selectList(qw);
    }

    /**
     * 根据对象特征分页查询匹配的对象列表
     *
     * @param page 分页对象
     * @param param 数据特征
     * @return 符合对象查询条件的对象数据
     */
    default IPage<T> selectPage(Page<T> page, T param) {
        QueryWrapper<T> qw = new QueryWrapper<>();
        if (param == null) {
            return selectPage(page, qw);
        }
        // 获得实体类对应的QueryWrapper对象
        qw = QueryUtil.entityQueryWrapper(param);
        return selectPage(page, qw);
    }

    /**
     * 根据通用查询对象获取分页数据
     *
     * @param page 分页对象
     * @param query 通用查询对象
     * @return 包含一页数据的分页对象
     */
    default IPage<T> queryPage(Page<T> page, Q query) {
        // 因为无法将通用查询对象中的属性与表中字段关联，默认实现中忽略query参数（实际使用中重写Mapper映射文件）
        QueryWrapper<T> qw = new QueryWrapper<>();
        return selectPage(page, qw);

        /*
        [SysUserMapper.xml]参考示例：
        <select id="queryPage" resultType="sysUser">
            SELECT
            `id`,
            `name`,
            `password`,
            `role_id`,
            `remark`,
            `status`,
            `create_time`,
            `modify_time`
            FROM `sys_user`
            <where>
                <if test="q.name != null and q.name != ''">
                    AND `name` = #{q.name}
                </if>
                <if test="q.keyword != null and q.keyword != ''">
                    AND `name` LIKE CONCAT('%',#{q.keyword},'%')
                </if>
                <if test="q.status != null">
                    AND `status` = #{q.status}
                </if>
                <if test="q.beginDate != null and q.beginDate != ''">
                    AND `create_time` &gt;= #{q.beginDate}
                </if>
                <if test="q.endDate != null and q.endDate != ''">
                    AND `create_time` &lt;= #{q.endDate}
                </if>
                <if test="q.attr.parentId != null">
                    AND `parent_id` = #{q.attr.parentId}
                </if>
            </where>
        </select>
        */
    }

}
